package com.airlines.crewassignment.service.ruleverification.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.airlines.base.config.datasource.FocMysqlDataSourceConfig;
import com.airlines.common.ListSplitUtil;
import com.airlines.common.Page;
import com.airlines.crewassignment.constant.CrewConstant;
import com.airlines.crewassignment.constant.RuleCodeConstant;
import com.airlines.crewassignment.daofocmysql.ruleverification.RuleVerificationMapper;
import com.airlines.crewassignment.domain.CrewLinkLineRoster;
import com.airlines.crewassignment.domain.rule.AssignmentRule;
import com.airlines.crewassignment.entity.ruleverification.RuleVerification;
import com.airlines.crewassignment.entity.ruleverification.RuleVerificationSummary;
import com.airlines.crewassignment.service.optaplanner.OptaplannerService;
import com.airlines.crewassignment.service.rule.AssignmentRuleService;
import com.airlines.crewassignment.service.ruleverification.RuleHardCheckService;
import com.airlines.crewassignment.service.ruleverification.RuleSoftCheckService;
import com.airlines.crewassignment.service.ruleverification.RuleVerificationService;

/**
 * @author xxxx
 * @date 2018/05/07 16:15:34
 * @company xxxx Airlines
 * @description 规则验证
 */
@Service
public class RuleVerificationServiceImpl implements RuleVerificationService {

    @Autowired
    private RuleVerificationMapper ruleVerificationMapper;
    
	@Autowired
	private RuleHardCheckService ruleHardCheckService;
	@Autowired
	private RuleSoftCheckService ruleSoftCheckService;
	@Autowired
	private  OptaplannerService optaplannerService;
	@Autowired
	private AssignmentRuleService assignmentRuleService;

    @Override
    public int insert(RuleVerification ruleVerification){
        return ruleVerificationMapper.insert(ruleVerification);
    }

    @Transactional(transactionManager=FocMysqlDataSourceConfig.TRANSACTION_MANAGER)
    @Override
    public boolean batchInsert(List<RuleVerification> ruleVerifications) {
        if(ruleVerifications.size() == 0){
            return false;
        }
        List<List<RuleVerification>> splitListAll = ListSplitUtil.split(ruleVerifications, 1000);
        for(List<RuleVerification> splitList : splitListAll){
        	ruleVerificationMapper.batchInsert(splitList);
        }
        return true ;
    }

    @Override
    public int deleteLogic(Integer id){
        return ruleVerificationMapper.deleteLogic(id);
    }


    @Override
    public int update(RuleVerification ruleVerification){
        return ruleVerificationMapper.update(ruleVerification);
    }

    @Override
    public RuleVerification get(Integer id){
        return ruleVerificationMapper.get(id);
    }

    @Override
    public List<RuleVerification> list(RuleVerification ruleVerification){
        return ruleVerificationMapper.list(ruleVerification);
    }

    @Override
    public Page list(RuleVerification ruleVerification, Page page){
        PageHelper.startPage(page.getPageNumber(), page.getPageSize());
        List<RuleVerification> list = ruleVerificationMapper.listByFuzzy(ruleVerification);
        PageInfo<RuleVerification> pageInfo = new PageInfo<RuleVerification>(list);
        page.setTotal(String.valueOf(pageInfo.getTotal()));
        page.setRows(pageInfo.getList());
        return page;
    }

    @Override
    public void deleteLogicByAfterDate(DateTime date) {
        ruleVerificationMapper.deleteLogicByAfterDate(date.toDate());
    }
    
    @Override
    public void deleteLogicByDate(DateTime dateStart,DateTime dateEnd,String dutyCode) {
        ruleVerificationMapper.deleteLogicByDate(dateStart.toDate(),dateEnd.toDate(),dutyCode);
    }

    @Transactional(transactionManager=FocMysqlDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void checkAndSaveAssignmentF(DateTime flightDateStart, DateTime flightDateEnd) {
		CrewLinkLineRoster clr = optaplannerService.crewLinkLineRosterInit(CrewConstant.DUTY_F,flightDateStart, flightDateEnd);
		List<RuleVerification> hardList = ruleHardCheckService.ruleHardCheckF(flightDateStart, flightDateEnd, clr);
		List<RuleVerification> softList = ruleSoftCheckService.ruleSoftCheckF(flightDateStart, flightDateEnd, clr);
		
		List<RuleVerification> rvList = new ArrayList<>();
		rvList.addAll(hardList);
		rvList.addAll(softList);
		
		this.deleteLogicByDate(flightDateStart,flightDateEnd,CrewConstant.DUTY_F);
		this.batchInsert(rvList);
		
	}

	@Override
	public List<RuleVerificationSummary> listRuleVerificationSummary(DateTime flightDateStart, DateTime flightDateEnd,
			String dutyCode, String workcode) {
		List<RuleVerification> list =ruleVerificationMapper
				.listBetweenFlightDate(flightDateStart.toDate(), flightDateEnd.toDate(), dutyCode, workcode);
		
		Set<RuleVerificationSummary> set = new HashSet<>();
		for(RuleVerification r : list){
			RuleVerificationSummary  rs = new RuleVerificationSummary();
			rs.setWorkcode(r.getWorkcode());
			rs.setDutyCode(r.getDutyCode());
			rs.setFlightDate(r.getFlightDate());
			rs.setCrewLinkLineNo(r.getCrewLinkLineNo());
			set.add(rs);
		}
		
		for(RuleVerificationSummary rs : set){
			for(RuleVerification r : list){
				if(StringUtils.equals(rs.getWorkcode(), r.getWorkcode())
						&& StringUtils.equals(rs.getDutyCode(), r.getDutyCode())
						&& DateUtils.isSameDay(rs.getFlightDate(), r.getFlightDate())
						&& rs.getCrewLinkLineNo().equals(r.getCrewLinkLineNo())
						&& r.getRuleScore() !=0
						){
					rs.getRuleVerificationlist().add(r);
					
				}
			}
		}
		List<AssignmentRule> assignmentRuleList = assignmentRuleService.listAll(CrewConstant.DUTY_F);
		for(RuleVerificationSummary rs : set){
			int hardSorce = 0;
			int softSorce = 0;
			int waringSorce = 0;
			for(RuleVerification r : rs.getRuleVerificationlist()){
				String ruleType = this.getRuleType(assignmentRuleList, r.getRuleCode());
				if(StringUtils.equals(RuleCodeConstant.HARD, ruleType)){
					hardSorce += r.getRuleScore();
				}
				if(StringUtils.equals(RuleCodeConstant.SOFT, ruleType)){
					softSorce += r.getRuleScore();
				}
				if(StringUtils.equals(RuleCodeConstant.WARING, ruleType)){
					waringSorce += r.getRuleScore();
				}
			}
			
			rs.setHardSorce(hardSorce);
			rs.setSoftSorce(softSorce);
			rs.setWaringSorce(waringSorce);
		}
		
		return new ArrayList<>(set);
	}

	private String getRuleType(List<AssignmentRule> assignmentRuleList,String ruleCode){
		for(AssignmentRule ar : assignmentRuleList){
			if(StringUtils.equals(ruleCode, ar.getRuleCode())){
				return ar.getRuleType();
			}
		}
		return null;
	}

}
